package com.chapter.sample.jvm.classload;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;

public class UserDefineClassLoader extends ClassLoader {


    private String rootPath;

    public UserDefineClassLoader(String rootPath) {
        this.rootPath = rootPath;
    }

    /**
     * 重写这个方法
     *
     * @param name The <a href="#binary-name">binary name</a> of the class
     * @return
     * @throws ClassNotFoundException
     */
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {

        //转换为以文件路径表示的文件
        String filePath = classToFilePath(name);
        //获取指定路径的class文件对应的二进制流数据
        byte[] data = getBytesFromPath(filePath);
        //自定义classLoader内部需要去defineClass()
        return defineClass(name, data, 0, data.length);
    }

    private byte[] getBytesFromPath(String filePath) {
        FileInputStream fis = null;
        ByteArrayOutputStream baos = null;
        try {
            fis = new FileInputStream(filePath);
            baos = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len;
            while ((len = fis.read(buffer)) != -1) {
                baos.write(buffer, 0, len);
            }
            return baos.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (baos != null) {
                    baos.close();
                }
            } catch (IOException e) {

            }

            try {
                if (fis != null) {
                    fis.close();
                }
            } catch (IOException e) {

            }
        }
        return null;
    }

    private String classToFilePath(String name) {

        return rootPath + "/" + name.replace(".", "/") + ".class";
    }

    public static void main(String[] args) {//加载 com.chapter.sample.jvm.load.Order
        try {
            UserDefineClassLoader userDefineClassLoader = new UserDefineClassLoader("/Library/dev/sample/chapter-common-platform/chapter-common-sample/src");
            Class orderClass1 = userDefineClassLoader.findClass("com.chapter.sample.jvm.load.Order");
            System.out.println(orderClass1);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

    }
}
